package com.epalmpay.service.posapi;

import com.epalmpay.exception.ApplicationException;
import com.epalmpay.entity.*;
import com.epalmpay.enumdef.ActivityEnum;
import com.epalmpay.enumdef.BizEnum;
import com.epalmpay.enumdef.CommonEnum;
import com.epalmpay.mapper.*;
import com.epalmpay.payplat.*;
import com.epalmpay.payplat.result.PayResult;
import com.epalmpay.payplat.result.UnPayConsumptionResult;
import com.epalmpay.service.activity.IActivityCouponService;
import com.epalmpay.service.jobservice.IProfitStatisService;
import com.epalmpay.service.member.IMemberService;
import com.epalmpay.util.*;
import com.epalmpay.util.payplat.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import static com.epalmpay.util.DateUtil.sdfTime;
import static com.epalmpay.util.DateUtil.sdfTimeHMS;

/**
 * Created by lifayi on 2017/9/14.
 */
@Service
public class PosApiServiceTransactional {

    @Resource
    private MemberICCardInfoMapper memberICCardInfoMapper;
    @Resource
    private MemberMapper memberMapper;
    @Resource
    private UserbaseMapper userbaseMapper;
    @Resource
    private CouponUserMapper couponUserMapper;
    @Resource
    private TradeOfflineMapper tradeOfflineMapper;
    @Resource
    private OrderServiceGoodMapper orderServiceGoodMapper;
    @Resource
    private OrderServiceGoodDetailMapper orderServiceGoodDetailMapper;
    @Resource
    private ShopUserMapper shopUserMapper;
    @Resource
    private BonusVerifyLogMapper bonusVerifyLogMapper;
    @Resource
    private BonusSendLogMapper bonusSendLogMapper;
    @Resource
    private BonusVerifyShopMapper bonusVerifyShopMapper;
    
    @Resource
    private IActivityCouponService activityCouponService;
    @Resource
    private PosApiServiceCacheable posApiServiceCacheable;
    @Resource
    private IMemberService memberService;

    @Autowired
    private IProfitStatisService profitStatisService;
    @Resource
    private BonusVerifyRuleMapper bonusVerifyRuleMapper;




    private Logger logger = Logger.getLogger(PosApiServiceTransactional.class);

    /*
    * 换卡事务控制
    * */
    void saveChangeCard(Long memberId, MemberICCardInfo memberICCardInfo) throws ApplicationException {
        int i = memberICCardInfoMapper.abandonMemberICCard(memberId);
        if(i != 1) {
            throw new ApplicationException("用户还未绑定实体卡");
        }
        memberICCardInfoMapper.insertSelective(memberICCardInfo);
    }

    /*
    * 实体卡开卡事务控制
    * */
    void saveMemberICCard(Userbase userbase, Member member, MemberICCardInfo memberICCardInfo, PayUserAccounts payUserAccounts) throws Exception {
        int i = userbaseMapper.insertSelective(userbase);
        if(i == 1) {
            member.setUserId(userbase.getId());
            int j = memberMapper.insertSelective(member);
            if(j == 1) {
                memberICCardInfo.setMemberId(member.getId());
                int z = memberICCardInfoMapper.insert(memberICCardInfo);
                if(z == 1) {
                    PayResult payResult = IPayAPI.individualUserAccounts(payUserAccounts);
                    if(payResult.getRespCode().equals("0000")) {
//                        member.setVirtualCard(payResult.getUserId());
//                        return memberMapper.updateByPrimaryKeySelective(member);
                        return;
                    }
                }
            }
        }
        throw new Exception("");
    }

    /*
    * 手机号开户事务控制
    */
    public void saveCreateMember(Userbase userbase, Member member, String groupNo) throws Exception {
        int i = userbaseMapper.insertSelective(userbase);
        if(i == 1) {
            member.setUserId(userbase.getId());
            int j = memberMapper.insertSelective(member);
            if(j == 1) {
                PayUserAccounts payUserAccounts = PayUserAccounts.initialize(groupNo, member.getVirtualCard(), "000", "000000000000000000",
                        "888888", "000000", "000000", "000@163.com",member.getPhone(), null, DateUtils.getDateTimeString("yyyyMMddHHmmss"),null);
                PayResult payResult = IPayAPI.individualUserAccounts(payUserAccounts);
                if(payResult.getRespCode().equals("0000")) {
                    return;
                }
            }
        }
        throw new Exception("支付平台开户失败");
    }

    
    /*
    * 锁定优惠券
    */
    public Map saveCalcAndLockCoupon(String couponCode, Long memberId, Integer tradeMoney, Long sid, String clientOrderNo) {
        Map coupon = couponUserMapper.listCouponByCouponCode(couponCode, memberId, ActivityEnum.CouponUseStatus.Received.getType(), tradeMoney);
        if(coupon == null) {
            return null;
        } else {
            Date now = new Date();
            //优惠券是否在有效期
            if((Integer)coupon.get("validTimeType") == ActivityEnum.ValidTimeType.FixedTime.getType()) {
                if(now.compareTo((Date) coupon.get("validStartTime")) < 0 || now.compareTo((Date) coupon.get("validEndTime")) > 0) {
                    return null;
                }
            } else if((Integer)coupon.get("validTimeType") == ActivityEnum.ValidTimeType.AfterGet.getType()) {
                Integer days = (Integer)coupon.get("days");
                Date validUseEnd = DateUtil.getDateNext((Date) coupon.get("getTime"), days);
                if(now.compareTo(validUseEnd) > 0) {
                    return null;
                }
            }

            //优惠券在门店是否可用
            String shopIdsStr = (String)coupon.get("shopIds");
            if(shopIdsStr == null) {
                return null;
            } else if(!shopIdsStr.equals("-1")) {
                String[] shopIds = shopIdsStr.split(",");
                boolean contains = false;
                for(int j = 0; j < shopIds.length; j++) {
                    if(Long.parseLong(shopIds[j]) == sid) {
                        contains = true;
                        break;
                    }
                }
                if(!contains) {
                    return null;
                }
            }
        }

        if(clientOrderNo != null) {
            int i = couponUserMapper.updateUseStatusByCouponId(couponCode, ActivityEnum.CouponUseStatus.locked.getType(), clientOrderNo);
            if(i != 1) {
                return null;
            }
        }

        System.out.print(coupon);

        return coupon;
    }
    
    
    /*
     * 锁定优惠券
     * */
     public Map calCoupon(String couponCode, Long memberId, Integer tradeMoney, Long sid) {
         Map coupon = couponUserMapper.listCouponByCouponCode(couponCode, memberId, ActivityEnum.CouponUseStatus.Received.getType(), tradeMoney);
         if(coupon == null) {
             return null;
         } else {
             Date now = new Date();
             //优惠券是否在有效期
             if((Integer)coupon.get("validTimeType") == ActivityEnum.ValidTimeType.FixedTime.getType()) {
                 if(now.compareTo((Date) coupon.get("validStartTime")) < 0 || now.compareTo((Date) coupon.get("validEndTime")) > 0) {
                     return null;
                 }
             } else if((Integer)coupon.get("validTimeType") == ActivityEnum.ValidTimeType.AfterGet.getType()) {
                 Integer days = (Integer)coupon.get("days");
                 Date validUseEnd = DateUtil.getDateNext((Date) coupon.get("getTime"), days);
                 if(now.compareTo(validUseEnd) > 0) {
                     return null;
                 }
             }

             //优惠券在门店是否可用
             String shopIdsStr = (String)coupon.get("shopIds");
             if(shopIdsStr == null) {
                 return null;
             } else if(!shopIdsStr.equals("-1")) {
                 String[] shopIds = shopIdsStr.split(",");
                 boolean contains = false;
                 for(int j = 0; j < shopIds.length; j++) {
                     if(Long.parseLong(shopIds[j]) == sid) {
                         contains = true;
                         break;
                     }
                 }
                 if(!contains) {
                     return null;
                 }
             }
         }
         return coupon;
     }

//    /*
//    * 消费返现 余额增加事务控制
//    * */
//    public int saveRebackMoney(TradeOffline tradeOffline, PayBalanceChange payBalanceChange, Long relatedTradeOfflineId) throws ApplicationException {
//        int i = tradeOfflineMapper.insertSelective(tradeOffline);
//        if(i == 1) {
//            int j = tradeOfflineMapper.updateRelatedTradeOfflineIdById(tradeOffline.getId(), relatedTradeOfflineId);
//            if(j == 1) {
//                PayResult payResult = IPayAPI.consumptionBalanceChange(payBalanceChange);
//                if (payResult.getRespCode().equals("0000")) {
//                	  tradeOffline.setTransOrderNo(payResult.getOrderId());
//                	  tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline);
//                    return 1;
//                }
//            }
//
//        }
//        throw new ApplicationException("支付平台余额增加失败");
//    }

    /*
    * 实体卡支付事务控制
    * */
//    void saveFinishICCardConsumption(TradeOffline tradeOffline, PayConsumption payConsumption) throws Exception {
//    	 int i = tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline);
//        if(i == 1) {
//            PayResult payResult = IPayAPI.consumption(payConsumption);
//            if(payResult.getRespCode().equals("0000")) {
//            	tradeOffline.setTransOrderNo(payResult.getOrderId());
//            	i = tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline);
//                return;
//            } else if (payResult.getRespCode().equals("0009")) {
//                throw new ApplicationException("账户余额不足");
//            } else if (payResult.getRespCode().equals("008X")) {
//                throw new ApplicationException("支付密码错误");
//            }
//        }
//        throw new Exception("交易失败");
//    }

    /*
    * 钱包支付事务控制
    * */
    void saveFinishQbPay(TradeOffline tradeOffline, PayMachineQRCode payMachineQRCode, Long sid) throws Exception {
        int i;
        if(tradeOffline.getId() == null) {
            i = tradeOfflineMapper.insertSelective(tradeOffline);
        } else {
            i = tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline);
        }

        System.out.print("--------------"+"开始"+"---------------------");

        //交易成功 是第一次交易给推荐者返现
        int result = memberService.updateMemberFirstTradeSend(tradeOffline.getId(),tradeOffline.getPayerId(),tradeOffline.getGroupId(),tradeOffline.getRealAmount());


        //核销优惠券
        if(tradeOffline.getDiscountAmount() != null && tradeOffline.getDiscountAmount() > 0) {
            int j = couponUserMapper.updateVerifyUserCouponByOrderId(tradeOffline.getOrderId());
            if(j == 0) {
                throw new ApplicationException("优惠券核销失败");
            }
        }

        //核销积分
        int x=0, y=0, z=0;
        if(tradeOffline.getDiscountAmount() != null && tradeOffline.getBonusAmount() > 0) {
            x = memberMapper.updateActualConsumeBonus(tradeOffline.getPayerId(), tradeOffline.getBonusAmount());
//            y = bonusVerifyShopMapper.updateByShopId(sid, tradeOffline.getBonusAmount());
            z = bonusVerifyLogMapper.confirmBonusVerify(tradeOffline.getId());

            //结算积分给门店 start
            Integer bonusamount = tradeOffline.getBonusAmount();
            Long groupId = tradeOffline.getGroupId();
            if(bonusamount != 0) {
                float settlerate = 0;
                //根据shopid获取积分结算规则
                BonusVerifyRule bonusVerifyRule = bonusVerifyRuleMapper.qyeryShopVerifyRule(sid);
                if (bonusVerifyRule != null) {//如果有门店自定义的
                    settlerate = bonusVerifyRule.getSettleRate();
                } else {//如果商圈给门店设置的
                    bonusVerifyRule = bonusVerifyRuleMapper.selectBonusSettleRate(sid, groupId);
                    if (bonusVerifyRule != null) {
                        settlerate = bonusVerifyRule.getSettleRate();
                    } else {
                        bonusVerifyRule = bonusVerifyRuleMapper.selectBonusVeriftyRuleByGroupId(groupId);
                        if (bonusVerifyRule != null) {
                            settlerate = bonusVerifyRule.getSettleRate();
                        }
                    }
                }

                //计算积分

                if (settlerate != 0) {
                    int bonus = (int) (bonusamount * settlerate / 100);
                    logger.info("+++++++结算到门店的积分+++++++"+bonus);
                    //积分结算给门店
                    BonusVerifyShop result1 = bonusVerifyShopMapper.bonusShopVerify(groupId,sid);
                    if(result1 !=null){
                        y=bonusVerifyShopMapper.updateShopVerifyBonus(groupId, sid, bonus);
                    }else{
                        BonusVerifyShop bonusVerifyShop = new BonusVerifyShop();
                        bonusVerifyShop.setGmtCreate(new Date());
                        bonusVerifyShop.setGmtModified(new Date());
                        bonusVerifyShop.setGroupId(groupId);
                        bonusVerifyShop.setShopId(sid);
                        bonusVerifyShop.setAmount(bonus);
                        bonusVerifyShop.setThisAmount(bonus);
                        bonusVerifyShop.setVerifiedAmount(bonus);
                        bonusVerifyShop.setStatus(1);
                        y=bonusVerifyShopMapper.insertSelective(bonusVerifyShop);
                    }
//                    y = bonusVerifyShopMapper.updateByShopId(sid, bonus);

                }

            }


        } else {
            x = 1; y = 1; z = 1;
        }

        if(i == 1 && x == 1 && y == 1 && z == 1) {
            PayResult payResult = IPayAPI.machineQr(payMachineQRCode);
            if(payResult != null) {
                String responseCode = payResult.getRespCode();
                if(responseCode.equals("0000")) {
                	tradeOffline.setTransOrderNo(payResult.getOrderId());
                	tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline);
                    //计算分润
                    try {
                        String shopfee = payResult.getMerchantFee();
                        if(shopfee != null) {
                            tradeOffline.setShopFee(Integer.parseInt(shopfee));
                            profitStatisService.saveOneOrderProfitCalculate(tradeOffline);
                        }
                    }catch (Exception e) {
                        e.printStackTrace();
                    }
                    return;
                } else if(responseCode.equals("EX00")) {
                    throw new ApplicationException("二维码已失效");
                } else if(responseCode.equals("0009")) {
                    throw new ApplicationException("账户余额不足");
                }
            }
        }
        throw new ApplicationException("交易失败");
    }

    /*
    * 订单取消
    * */
    void saveDoOrderCancel(String orderNo) throws ApplicationException {
        int i = tradeOfflineMapper.updateCancelByOrderNo(orderNo);
        if(i == 1) {
            TradeOffline tradeOffline = tradeOfflineMapper.selectByOrderIdStatus(orderNo, (byte) BizEnum.TransactionStatus.Cancel.getType());
            
            couponUserMapper.updateUnlockCouponOnMember(tradeOffline.getOrderId());
            couponUserMapper.updateUnlockCouponOnNoMember(tradeOffline.getOrderId());
            if(tradeOffline.getBonusAmount() != null && tradeOffline.getBonusAmount() > 0) {
                int j = bonusVerifyLogMapper.updateStatusByOrderId(tradeOffline.getId(), ActivityEnum.BonusVerityStatus.OrderCancel.getType());
                if(j == 1) {
                    int z = memberMapper.updateMemberBonusUnlock(tradeOffline.getPayerId(), tradeOffline.getBonusAmount());
                    if(z == 1) {
                        return;
                    } else {
                        throw new ApplicationException("订单取消失败");
                    }
                }
            }
            return;
        }
        throw new ApplicationException("订单取消失败");
    }

    /*
    * 券码核销事务处理
    * */
    public void saveDoCouponVerify(OrderServiceGood orderServiceGood, OrderServiceGoodDetail orderServiceGoodDetail,
                                   PayBalanceChange payBalanceChange, TradeOffline tradeOffline) throws Exception {
//        int z = 1;
//        if(tradeOffline != null) {
//            z = tradeOfflineMapper.insertSelective(tradeOffline);
//            orderServiceGoodDetail.setVerifyTradeId(tradeOffline.getId());
//        }
//        if(z == 1) {
            int i = orderServiceGoodMapper.updateByPrimaryKeySelective(orderServiceGood);
            if(i == 1) {
                int j = orderServiceGoodDetailMapper.updateByPrimaryKeySelective(orderServiceGoodDetail);
                if(j == 1) {
//                    if(payBalanceChange != null) {
//                        PayResult payResult = IPayAPI.consumptionBalanceChangeMerchant(payBalanceChange);
//                        if(payResult.getRespCode().equals("0000")) {
//                            return;
//                        } else {
//                            throw new Exception("券码核销失败");
//                        }
//                    }
                    return;
                }
            }
//        }
        throw new Exception("券码核销失败");
    }

    /*
    * 核销优惠券事务控制
    * */
   public void saveVerifyCouponAndUpdateTrade(TradeOffline tradeOffline, String couponSn, Long sid) throws ApplicationException {
        int z = tradeOfflineMapper.replaceInto(tradeOffline);
        int j=0;
        if(z == 1 || z == 2) {
            if(tradeOffline.getBonusAmount()!=null&&tradeOffline.getBonusAmount() > 0) {
                int i = memberMapper.updateActualConsumeBonus(tradeOffline.getPayerId(), tradeOffline.getBonusAmount());


                //结算积分给门店 start
                Integer bonusamount = tradeOffline.getBonusAmount();
                Long groupId = tradeOffline.getGroupId();
                if(bonusamount != 0) {
                    float settlerate = 0;
                    //根据shopid获取积分结算规则
                    BonusVerifyRule bonusVerifyRule = bonusVerifyRuleMapper.qyeryShopVerifyRule(sid);
                    if (bonusVerifyRule != null) {//如果有门店自定义的
                        settlerate = bonusVerifyRule.getSettleRate();
                    } else {//如果商圈给门店设置的
                        bonusVerifyRule = bonusVerifyRuleMapper.selectBonusSettleRate(sid, groupId);
                        if (bonusVerifyRule != null) {
                            settlerate = bonusVerifyRule.getSettleRate();
                        } else {
                            bonusVerifyRule = bonusVerifyRuleMapper.selectBonusVeriftyRuleByGroupId(groupId);
                            if (bonusVerifyRule != null) {
                                settlerate = bonusVerifyRule.getSettleRate();
                            }
                        }
                    }
                    //计算积分
                    if (settlerate != 0) {
                        int bonus = (int) (bonusamount * settlerate / 100);
                        logger.info("+++++++结算到门店的积分+++++++"+bonus);
                        //积分结算给门店
                        BonusVerifyShop result1 = bonusVerifyShopMapper.bonusShopVerify(groupId,sid);
                        if(result1 !=null){
                            j=bonusVerifyShopMapper.updateShopVerifyBonus(groupId, sid, bonus);
                        }else{
                            BonusVerifyShop bonusVerifyShop = new BonusVerifyShop();
                            bonusVerifyShop.setGmtCreate(new Date());
                            bonusVerifyShop.setGmtModified(new Date());
                            bonusVerifyShop.setGroupId(groupId);
                            bonusVerifyShop.setShopId(sid);
                            bonusVerifyShop.setAmount(bonus);
                            bonusVerifyShop.setThisAmount(bonus);
                            bonusVerifyShop.setVerifiedAmount(bonus);
                            bonusVerifyShop.setStatus(1);
                            j=bonusVerifyShopMapper.insertSelective(bonusVerifyShop);
                        }

                    }

                }

                logger.info(">>>>>>积分结算结束>>>>>");


//                int j = bonusVerifyShopMapper.updateByShopId(sid, tradeOffline.getBonusAmount());
                bonusVerifyLogMapper.confirmBonusVerify(tradeOffline.getId());
                if(i != 1 || j != 1) {
                    throw new ApplicationException("积分核销失败");
                }
            }

            if (!Tools.isEmpty(couponSn)) {
                try {
                    activityCouponService.updateVerifyCoupon(couponSn, sid,tradeOffline);
                    return;
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new ApplicationException("优惠券核销失败");
                }
            } else {
                return;
            }
        }
        throw new ApplicationException("优惠券核销失败");
    }

    /***
     * 核销优惠券事务控制
     * 扣除之前的积分是未冻结的
     */
  public   void saveVerifyCouponBonus(TradeOffline tradeOffline, Long sid) throws ApplicationException {

         int z = tradeOfflineMapper.replaceInto(tradeOffline);
         int bonus=0;
         int j = 0;
         if(z == 1 || z == 2) {
             if(tradeOffline.getBonusAmount()!=null&&tradeOffline.getBonusAmount() > 0) {
            	  int i = memberMapper.updateActualConsumeBonus(tradeOffline.getPayerId(), tradeOffline.getBonusAmount());


                 //积分结算到门店开始
                 if(sid !=null){

                     //结算积分给门店 start
                     Integer bonusamount = tradeOffline.getBonusAmount();
                     Long groupId = tradeOffline.getGroupId();
                     if(bonusamount != 0) {
                         float settlerate = 0;
                         //根据shopid获取积分结算规则
                         BonusVerifyRule bonusVerifyRule = bonusVerifyRuleMapper.qyeryShopVerifyRule(sid);
                         if (bonusVerifyRule != null) {//如果有门店自定义的
                             settlerate = bonusVerifyRule.getSettleRate();
                         } else {//如果商圈给门店设置的
                             bonusVerifyRule = bonusVerifyRuleMapper.selectBonusSettleRate(sid, groupId);
                             if (bonusVerifyRule != null) {
                                 settlerate = bonusVerifyRule.getSettleRate();
                             } else {
                                 bonusVerifyRule = bonusVerifyRuleMapper.selectBonusVeriftyRuleByGroupId(groupId);
                                 if (bonusVerifyRule != null) {
                                     settlerate = bonusVerifyRule.getSettleRate();
                                 }
                             }
                         }

                         //计算积分

                         if (settlerate != 0) {
                              bonus = (int) (bonusamount * settlerate / 100);
                             logger.info("+++++++结算到门店的积分+++++++"+bonus);
                             //积分结算给门店
                             BonusVerifyShop result1 = bonusVerifyShopMapper.bonusShopVerify(groupId,sid);
                             if(result1 !=null){
                                 j=bonusVerifyShopMapper.updateShopVerifyBonus(groupId, sid, bonus);
                             }else{
                                 BonusVerifyShop bonusVerifyShop = new BonusVerifyShop();
                                 bonusVerifyShop.setGmtCreate(new Date());
                                 bonusVerifyShop.setGmtModified(new Date());
                                 bonusVerifyShop.setGroupId(groupId);
                                 bonusVerifyShop.setShopId(sid);
                                 bonusVerifyShop.setAmount(bonus);
                                 bonusVerifyShop.setThisAmount(bonus);
                                 bonusVerifyShop.setVerifiedAmount(bonus);
                                 bonusVerifyShop.setStatus(1);
                                j= bonusVerifyShopMapper.insertSelective(bonusVerifyShop);
                             }

                         }


                     }
                     //结算积分给门店 end

                 }

//                 int j = bonusVerifyShopMapper.updateByShopId(sid, tradeOffline.getBonusAmount());

                 bonusVerifyLogMapper.confirmBonusVerify(tradeOffline.getId());
                 if(i != 1 || j != 1) {
                     throw new ApplicationException("积分核销失败");
                 }
             }
            

             try {
                 activityCouponService.updateVerifyCoupon(null, sid, tradeOffline);
                 return;
             } catch (Exception e) {
                 e.printStackTrace();
                 throw new ApplicationException("优惠券核销失败");
             }
         }
         throw new ApplicationException("优惠券核销失败");
     }

     
    
    /*
    * 钱包退款事务控制
    * */
    public void saveQbRefund(Long memberId, TradeOffline tradeOffline, UnPayConsumption unPayConsumption, Long oldTradeOfflineId, Integer point,Integer realAmount) throws ApplicationException {
        int i = tradeOfflineMapper.insertSelective(tradeOffline);
        if(i == 1) {
            TradeOffline tradeOfflineOld = new TradeOffline();
            tradeOfflineOld.setId(oldTradeOfflineId);
            tradeOfflineOld.setTransactionStatus((byte) BizEnum.TransactionStatus.ISRefund.getType());
            int j = tradeOfflineMapper.updateByPrimaryKeySelective(tradeOfflineOld);
            if(j == 1) {//积分余额退回
                memberMapper.updateMemberBonusById(tradeOffline.getPayerId(), point);
                bonusVerifyLogMapper.updateStatusByOrderId(oldTradeOfflineId, ActivityEnum.BonusVerityStatus.TradeCancel.getType());
                shopUserMapper.addRefund(memberId, Long.parseLong(tradeOffline.getReceiverId()),tradeOffline.getRealAmount());
                UnPayConsumptionResult unPayConsumptionResult = IPayAPI.unPayConsumption(unPayConsumption);
                if(unPayConsumptionResult != null && unPayConsumptionResult.getRespCode().equals("0000")) {
                    return;
                }
            }
        }
        throw new ApplicationException("退款交易失败");
    }

    /**
     * 其他退款事务处理   退还使用的积分等信息到用户账户上  核销门店吧吧结算的积分退回
     * @param newTradeOrderNum
     * @param authCode
     * @param payType
     * @param tradeOffline
     * @throws ApplicationException
     */
    public void saveOtherRefund(String newTradeOrderNum,String authCode,int payType,TradeOffline tradeOffline) throws ApplicationException {
    	
    	Long oldTradeId=tradeOffline.getId();
    	Integer point=tradeOffline.getBonusAmount();
        Date date = new Date();

        //查询结算到门店多少积分
        BonusVerifyLog bonusVerifyLog=bonusVerifyLogMapper.queryBonusVerifyLogByTradeId(tradeOffline.getId());
        Integer settingAmount=0;
        if(bonusVerifyLog !=null && bonusVerifyLog.getSettingAmount()!=null){
            settingAmount=bonusVerifyLog.getSettingAmount();
        }


        tradeOffline.setTransactionStatus((byte) BizEnum.TransactionStatus.ISRefund.getType());
        int i = tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline);
        
        
//        if(tradeOffline.getPayerId()==null){
//        	return;
//        }
//
        TradeOffline tradeOfflineNew = new TradeOffline();
        tradeOfflineNew.setGroupId(tradeOffline.getGroupId());
        tradeOfflineNew.setOrderId(newTradeOrderNum);
        tradeOfflineNew.setOldOrderId(tradeOffline.getId());
        tradeOfflineNew.setRealAmount(-(tradeOffline.getRealAmount()));
        tradeOfflineNew.setOrderAmount(-(tradeOffline.getOrderAmount()));
        tradeOfflineNew.setBonusValue(-(tradeOffline.getBonusValue()));
        tradeOfflineNew.setBonusAmount(-(tradeOffline.getBonusAmount()));
        tradeOfflineNew.setTransOrderNo(authCode);
        tradeOfflineNew.setTransactionStatus((byte) BizEnum.TransactionStatus.Refund.getType());
        if(payType!=0){
        	tradeOfflineNew.setPayType((byte) payType);
        }else{
        	tradeOfflineNew.setPayType(null);
        }
        tradeOfflineNew.setTransactionType((byte) BizEnum.TransactionType.Refund.getType());
        tradeOfflineNew.setGmtCreate(date);
        tradeOfflineNew.setGmtModified(date);
       //非会员
        if(tradeOffline.getPayerId()==null){
            tradeOfflineNew.setPayerId(null);
            tradeOfflineNew.setPayerName(null);
        }else{
            tradeOfflineNew.setPayerId(tradeOffline.getPayerId());
            tradeOfflineNew.setPayerName(tradeOffline.getPayerName());
        }
        tradeOfflineNew.setPayerType(tradeOffline.getPayerType());
        tradeOfflineNew.setReceiverId(tradeOffline.getReceiverId()); 
        tradeOfflineNew.setReceiverName(tradeOffline.getReceiverName());

        //会员
        if(tradeOffline.getPayerId()!=null){
           // 扣除 消费次数和累计退款次数
            shopUserMapper.addRefund(tradeOffline.getPayerId(), Long.parseLong(tradeOffline.getReceiverId()),tradeOffline.getRealAmount());


        }

        if(i == 1) {
            int j = tradeOfflineMapper.insertSelective(tradeOfflineNew);
            if(j == 1) {
                if(point > 0) {
                    bonusVerifyLogMapper.updateStatusByOrderId(oldTradeId, ActivityEnum.BonusVerityStatus.TradeCancel.getType());
                    memberMapper.updateMemberBonusById(tradeOffline.getPayerId(), point);
                    //核销门店退回得到的结算积分
                    if(bonusVerifyLog !=null){
                        bonusVerifyShopMapper.updateShopBonusInfo(bonusVerifyLog.getShopId(),settingAmount);
                    }
                }
                return;
            }
        }
        throw new ApplicationException("退款处理失败");
    }

    
//    /*
//     * 其他退款事务处理
//     * */
//     public void saveOtherRefund(TradeOffline tradeOffline1, Long oldTradeId, Integer point) throws ApplicationException {
//         TradeOffline tradeOffline = new TradeOffline();
//         tradeOffline.setId(oldTradeId);
//         shopUserMapper.addRefund(tradeOffline1.getPayerId(), Long.parseLong(tradeOffline1.getReceiverId()),tradeOffline1.getRealAmount());
//         tradeOffline.setTransactionStatus((byte) BizEnum.TransactionStatus.ISRefund.getType());
//         int i = tradeOfflineMapper.updateByPrimaryKeySelective(tradeOffline);
//         if(i == 1) {
//             int j = tradeOfflineMapper.insertSelective(tradeOffline1);
//             if(j == 1) {
//                 if(point > 0) {
//                     bonusVerifyLogMapper.updateStatusByOrderId(oldTradeId, ActivityEnum.BonusVerityStatus.TradeCancel.getType());
//                     memberMapper.updateMemberBonusById(tradeOffline1.getPayerId(), point);
//                 }
//                 return;
//             }
//         }
//         throw new ApplicationException("退款处理失败");
//     }
    
    
    
    /*
    * 退款红包处理
    * */
//    void saveRefundUserRedpackage(TradeOffline tradeOffline, PayBalanceChange payBalanceChange) throws ApplicationException {
//        int i = tradeOfflineMapper.insertSelective(tradeOffline);
//        if(i == 1) {
//            PayResult payResult = IPayAPI.consumptionBalanceChange(payBalanceChange);
//            if(payResult.getRespCode().equals("0000")) {
//                return;
//            }
//        }
//        throw new ApplicationException("退款红包(或返现)处理失败");
//    }

    /*
    * 创建交易流水并锁定积分
    * */
    void saveCreateOrder(Member member, TradeOffline tradeOffline, BonusVerifyLog bonusVerifyLog) throws ApplicationException {
        int point = tradeOffline.getBonusAmount();
        int i = memberMapper.updateMemberBonusLock(member.getId(), point);
        if(i == 1) {
            int j = tradeOfflineMapper.insertSelective(tradeOffline);
            if(j == 1) {
                if(bonusVerifyLog.getAdjustAmount() > 0) {
                    bonusVerifyLog.setOrderId(tradeOffline.getId());
                    int x = bonusVerifyLogMapper.insertSelective(bonusVerifyLog);
                    if(x == 1) {
                        return;
                    }
                }
                return;
            }
        }
        throw new ApplicationException("积分锁定失败");
    }

    /*
    * 用户发放积分
    * */
    public void saveSendBonus(BonusSendLog bonusSendLog, Long memberId, Integer backPoint, BonusSendRule bonusSendRule,
                       Map<String, Object> userBonusSendRecords) throws ApplicationException {
        int freezeNum = bonusSendLogMapper.countMemberStatusSendLog(memberId, ActivityEnum.BonusSendStatus.Freezing.getType());
        int j = 0;
        if(freezeNum > 0 || (bonusSendRule.getSendSingleMax() != 0 && backPoint > bonusSendRule.getSendSingleMax()) ||
                (bonusSendRule.getSendDayMax() != 0 && (backPoint + ((BigDecimal)userBonusSendRecords.get("sendAmount")).intValue()) > bonusSendRule.getSendDayMax()) ||
                (bonusSendRule.getSendDayCount() != 0 && (1 + (Long)userBonusSendRecords.get("sendCount")) > bonusSendRule.getSendDayCount())) {
            bonusSendLog.setAdjustStatus(ActivityEnum.BonusSendStatus.Freezing.getType());
            bonusSendLog.setIsFlag(CommonEnum.YesOrNo.Yes.getType());
            j = memberMapper.updateBonusFreezeById(memberId, backPoint);
            logger.debug(">>>>>>> 积分发放超限，已冻结");
        } else if(bonusSendRule.getSendAccountedTime() != 0) {
            bonusSendLog.setAdjustStatus(ActivityEnum.BonusSendStatus.Accounting.getType());
            bonusSendLog.setAccountingTime(DateUtil.getTimeByHour(bonusSendRule.getSendAccountedTime()));
            j = memberMapper.updateBonusPreAcountById(memberId, backPoint);
            logger.debug(">>>>>>>> 积分待入账，到账时间" + bonusSendLog.getAccountingTime());
        } else {
            bonusSendLog.setAdjustStatus(ActivityEnum.BonusSendStatus.Accounted.getType());
            bonusSendLog.setAccountingTime(new Date());
            j = memberMapper.updateMemberBonusById(memberId, backPoint);
            logger.debug(">>>>>>>> 积分已入账");
        }
        if(j == 1) {
            int i = bonusSendLogMapper.insertSelective(bonusSendLog);
            if(i == 1) {
                return;
            }
        }
        throw new ApplicationException("用户积分发放失败");
    }

    /*
    * 用户积分退回
    * */
    void saveMemberBonusRefund(BonusSendLog bonusSendLog, Member member) throws ApplicationException {
        Integer status = bonusSendLog.getAdjustStatus();
        bonusSendLog.setAdjustStatus(ActivityEnum.BonusSendStatus.TradeCancel.getType());
        int i = bonusSendLogMapper.updateByPrimaryKeySelective(bonusSendLog);
        if(i == 1) {
            Long memberId = member.getId();
            Integer bonusAmount = bonusSendLog.getAdjustAmount();
            if(status == ActivityEnum.BonusSendStatus.Freezing.getType()) {
                memberMapper.updateBonusFreezeById(memberId, -(bonusAmount));
            } else if(status == ActivityEnum.BonusSendStatus.Accounting.getType()) {
                memberMapper.updateBonusPreAcountById(memberId, -(bonusAmount));
            } else if(status == ActivityEnum.BonusSendStatus.Accounted.getType()) {
                memberMapper.deductionActualConsumeBonus(memberId, bonusAmount);
            } else {
                throw new ApplicationException("积分状态错误");
            }
            return;
        }
        throw new ApplicationException("积分退回失败");
    }

    /*
    *异业优惠券锁定
    */
    void saveLockOtherCoupon(TradeOffline tradeOffline, Long groupId, String couponCode, Long sid, Date date, Long id) throws ApplicationException {
        int i = tradeOfflineMapper.insertSelective(tradeOffline);
        if(i == 1) {
            int j = couponUserMapper.updateLockCoupon(id, sid, date,tradeOffline.getOrderId(), tradeOffline.getId());
            if(j == 1) {
                return;
            }
        }
        throw new ApplicationException("服务器处理错误");
    }

    //用户最大最小可核销积分计算
    public Map<String, Integer> userCanVerifyBonus(Long sid, Long groupId, Member member, Date date, Integer tradeMoney) {
        int pointUseMax, frequency_min, verifyRate = 0, cantVerifyReason = 0;
        //查询门店是否可以使用积分核销
        BonusVerifyShop bonusVerifyShop = bonusVerifyShopMapper.selectByShopId(sid);

        if(bonusVerifyShop != null) {

            //积分核销规则
            BonusVerifyRule bonusVerifyRule = posApiServiceCacheable.shopBonusVerifyRule(sid, groupId);

            if(bonusVerifyRule != null) {
                verifyRate = bonusVerifyRule.getVerifyRate();
                Date hourAndSecond = null;
                try {
                    hourAndSecond = DateUtil.cutoutHourAndSecond(date);
                } catch (ParseException e) {
                    e.printStackTrace();
                }

                Date dateStart = DateUtil.getDayStart(date);
                Date dateEnd = DateUtil.getAfterDay(dateStart, 1);
                Map<String, Object> userBonusInfo =  bonusVerifyLogMapper.getMemberDayBonusVerifyCount(member.getId(), dateStart, dateEnd);

                if(hourAndSecond == null) {
                    pointUseMax = frequency_min = 0;
                    cantVerifyReason = 100;
                } else if(bonusCanVerify(hourAndSecond, bonusVerifyRule)) {
                    if(bonusVerifyRule.getVerifySingleMaxType() == ActivityEnum.BonusVerifyComputeType.Fixed.getType()) {
                        pointUseMax = bonusVerifyRule.getVerifySingleMax();
                    } else {
                        pointUseMax = new BigDecimal(bonusVerifyRule.getVerifySingleMax()).divide(new BigDecimal(100), 2 , BigDecimal.ROUND_FLOOR)
                                .multiply(new BigDecimal(tradeMoney).divide(new BigDecimal(100), 2, BigDecimal.ROUND_FLOOR)).multiply(new BigDecimal(verifyRate)).intValue();
                    }

                    if(bonusVerifyRule.getVerifySingleMinType() == ActivityEnum.BonusVerifyComputeType.Fixed.getType()) {
                        frequency_min = bonusVerifyRule.getVerifySingleMin();
                    } else {
                        frequency_min = new BigDecimal(bonusVerifyRule.getVerifySingleMin()).divide(new BigDecimal(100), 2 , BigDecimal.ROUND_FLOOR)
                                .multiply(new BigDecimal(tradeMoney).divide(new BigDecimal(100), 2, BigDecimal.ROUND_FLOOR)).multiply(new BigDecimal(verifyRate)).intValue();
                    }
                    Integer verifyCount = Integer.parseInt(String.valueOf(userBonusInfo.get("verifyCount")));
                    Integer verifyAmount =Integer.parseInt(String.valueOf(userBonusInfo.get("verifyAmount")));
                    if(verifyCount >= bonusVerifyRule.getVerifyDayCount() ||
                            bonusVerifyRule.getVerifyDaySum() <= verifyAmount) {   //已超过最大限额或者最大交易总笔数
                        pointUseMax = frequency_min = 0;
                        cantVerifyReason = 5;
                    } else {
                        int i = (bonusVerifyRule.getVerifyDaySum() - verifyAmount);
                        pointUseMax = pointUseMax < i ? pointUseMax : i;
                        pointUseMax = pointUseMax < member.getBonusAmount() ? pointUseMax : member.getBonusAmount();
                        if(pointUseMax < frequency_min) {       //最大可用积分数小于风控最小值
                            pointUseMax = frequency_min = 0;
                            cantVerifyReason = 4;
                        }
                    }
                } else {    //当前时段不可核销
                    pointUseMax = frequency_min = 0;
                    cantVerifyReason = 3;
                }
            } else {    //未设置积分默认规则
                pointUseMax = frequency_min = 0;
                cantVerifyReason = 2;
            }
        } else {     //门店不可核销积分
            pointUseMax = frequency_min = 0;
            cantVerifyReason = 1;
        }

        Map<String, Integer> userCanVerifyBonus = new HashMap<>();
        userCanVerifyBonus.put("pointUseMax", pointUseMax);//最大可兑换积分
        userCanVerifyBonus.put("frequency_min", frequency_min);//最小可兑换积分
        userCanVerifyBonus.put("verifyRate", verifyRate);//兑换比例
        userCanVerifyBonus.put("cantVerifyReason", cantVerifyReason);//积分不可核销原因
        return userCanVerifyBonus;
    }
    
    //当前时间是否可核销判断
    private boolean bonusCanVerify(Date date, BonusVerifyRule bonusVerifyRule) {
    	System.out.println(bonusVerifyRule.getVerifyTimeType());
//        String date1 = DateUtil.fomatDate(date, sdfTimeHMS);


        return bonusVerifyRule.getVerifyTimeType() == ActivityEnum.TimeRangeType.AllDay.getType() ||
                (bonusVerifyRule.getVerifyTimeFrom1() != null &&
                        bonusVerifyRule.getVerifyTimeFrom1().compareTo(date) <= 0 && bonusVerifyRule.getVerifyTimeTo1().compareTo(date) >= 0) ||
                (bonusVerifyRule.getVerifyTimeFrom2() != null &&
                        bonusVerifyRule.getVerifyTimeFrom2().compareTo(date) <= 0 && bonusVerifyRule.getVerifyTimeTo2().compareTo(date) >= 0) ||
                (bonusVerifyRule.getVerifyTimeFrom3() != null &&
                        bonusVerifyRule.getVerifyTimeFrom3().compareTo(date) <= 0 && bonusVerifyRule.getVerifyTimeTo3().compareTo(date) >= 0);
    }




    public static void main(String[] args) {

        Date date = new Date();
        System.out.print(date+"-------------");

        String stringDate= "1970-01-01 "+"10:10"+":00";


        Date date2 = DateUtil.fomatDate(stringDate, sdfTime);
        System.out.print(date2);



    }

}
